<?php
declare (strict_types = 1);

use think\facade\Cache;

class RedisLock
{
    private $redisObj;//redis对象
    private $prefix = ''; //redis的key前缀,防止多个项目使用同一个redis,key覆盖的问题
    /**
     *redis锁
     **/
    public function __construct()
    {
        //获取Redis对象
        $this->redisObj = Cache::store('redis')->handler();
        $this->prefix = config('cache.prefix');
    }

    /**
     * 获取锁
     * @param  string $key 锁标识
     * @param  int $expire 锁过期时间
     * @param  int $db 库序号
     * @return boolean
     */
    public function lock(string $key, int $expire = 5, $db = 7) :bool
    {
        $key = $this->prefix . $key;
        $this->redisObj->select($db);
        $is_lock = $this->redisObj->setnx($key, time() + $expire);
        // 存在锁
        if (!$is_lock) {
            // 判断锁是否过期
            $lock_time = $this->redisObj->get($key);
            // 锁已过期，删除锁，重新设置
            if (time() > $lock_time) {
                $this->unlock($key);
                $is_lock = $this->redisObj->setnx($key, time() + $expire);
            }
        }
        return $is_lock ? true : false;
    }

    /**
     * 释放锁
     * @param  string $key 锁标识
     * @return boolean
     */
    public function unlock(string $key) :bool
    {
        $key = strpos($key, $this->prefix) === false ? $this->prefix . $key : $key;
        return $this->redisObj->del($key) ? true : false;
    }
}